import type { DownloadCompleteArgs, DownloadErrorArgs, DownloadParam, DownloadProgressArgs } from "@common/http-service-types";
import { downloadFile } from "@/framework/util/http";
import type { UnzipCompleteArgs, UnzipErrorArgs, UnzipFileArgs } from "@common/archives-file-types";
import { unzipFile } from "@/framework/util/archvie-file";
import type { Ref } from "vue";
import type { ToolInstallState } from "@/pages/tools/common/types";
import path from "path-browserify-esm";
import { deleteFile } from "@/framework/util/fs";
import { noop } from "@/framework/util/warning";
import { message } from "ant-design-vue";

export function getPlatform() {
  return proc.platform === "win32" ? "win" : proc.platform;
}

export interface DownloadArgs extends DownloadParam {
  // 进度回调
  progress?: (e: DownloadProgressArgs) => void;
}

/**
 * 下载文件
 * @param args
 */
export function download(args: DownloadArgs): Promise<DownloadCompleteArgs> {
  return new Promise((resolve, reject) => {
    const id = args.id;
    downloadFile({ id, url: args.url, savePath: args.savePath });

    const onProgress = (_: any, pargs: DownloadProgressArgs) => args.progress?.(pargs);

    const onError = (_: any, args: DownloadErrorArgs) => {
      reject(`下载失败: ${args.message}`);
      unsubscribe();
    };
    const onComplete = (_: any, args: DownloadCompleteArgs) => {
      resolve(args);
      unsubscribe();
    };

    ipc.on(`file:download:progress:${id}`, onProgress);
    ipc.on(`file:download:error:${id}`, onError);
    ipc.on(`file:download:complete:${id}`, onComplete);

    function unsubscribe() {
      ipc.off(`file:download:progress:${id}`, onProgress);
      ipc.off(`file:download:complete:${id}`, onComplete);
      ipc.off(`file:download:error:${id}`, onError);
    }
  });
}

export interface UnzipArgs extends UnzipFileArgs {}

/**
 * 解押文件
 * @param args
 */
export function unzip(args: UnzipArgs): Promise<UnzipCompleteArgs> {
  return new Promise((resolve, reject) => {
    const id = args.id;
    unzipFile(args);

    const onUnzipError = (_: any, args: UnzipErrorArgs) => {
      reject(`解压失败: ${args.message}`);
      unsubscribe();
    };
    const onUnzipComplete = (_: any, args: UnzipCompleteArgs) => {
      resolve(args);
      unsubscribe();
    };

    ipc.on(`unzip:error:${id}`, onUnzipError);
    ipc.on(`unzip:complete:${id}`, onUnzipComplete);

    function unsubscribe() {
      ipc.off(`unzip:error:${id}`, onUnzipError);
      ipc.off(`unzip:complete:${id}`, onUnzipComplete);
    }
  });
}

export interface InstallArchiveFileArgs extends UnzipArgs {
  // 安装状态引用
  state?: Ref<ToolInstallState>;
  // 是否删除压缩文件[=true]
  deleteArchive?: boolean;
  // 压缩包解压成功回调
  unzipComplete: (e: UnzipCompleteArgs) => void | Promise<void>;
}

export interface DownloadAndUnzipArgs extends DownloadArgs {
  // 压缩包解压输出目录
  archiveOutput: string;
  // 安装状态引用
  state?: Ref<ToolInstallState>;
  // 是否删除压缩文件[=true]
  deleteArchive?: boolean;
  // 下载成功回调
  downloadSuccess?: () => void;
  // 压缩包解压成功回调
  unzipComplete: (e: UnzipCompleteArgs) => void | Promise<void>;
}

/**
 * 下载并解压文件
 */
export function downloadAndUnzip(args: DownloadAndUnzipArgs): Promise<void> {
  return new Promise(async (resolve, reject) => {
    if (args.state) args.state.value = "downloading";
    try {
      if (__DEV__) console.log("[install-tool] downloading file:", args.url);
      await download({ id: args.id, url: args.url, savePath: args.savePath, progress: args.progress });
      if (__DEV__) console.log("[install-tool] download success:", args.savePath);
      args.downloadSuccess?.();
      await installArchiveFile0({
        id: args.id,
        state: args.state,
        archiveFile: args.savePath,
        outputDir: args.archiveOutput,
        deleteArchive: args.deleteArchive,
        unzipComplete: args.unzipComplete,
      });
      resolve();
    } catch (e: any) {
      if (args.state) args.state.value = "initial";
      console.error("[install-tool] install error: ", args.url, e);
      reject(e);
    } finally {
      if (args.state) args.state.value = "initial";
    }
  });
}

async function installArchiveFile0(args: InstallArchiveFileArgs) {
  if (args.state) args.state.value = "unziping";
  const unzipOutDir = path.dirname(args.archiveFile);

  if (__DEV__) console.log("[install-tool] unziping file:", args.archiveFile, ">", unzipOutDir);

  const res = await unzip({ id: args.id, archiveFile: args.archiveFile, outputDir: unzipOutDir });

  if (__DEV__) console.log("[install-tool] unzip success:", res);

  if (args.state) args.state.value = "installing";
  await args.unzipComplete(res);
  if (args.deleteArchive !== false) {
    if (__DEV__) console.log("[install-tool] delete archive file:", args.archiveFile);
    deleteFile(args.archiveFile).catch(noop);
  }
}

/**
 * 安装压缩文件
 */
export async function installArchiveFile(args: InstallArchiveFileArgs) {
  if (args.state?.value === "unziping") return;
  try {
    await installArchiveFile0(args);
  } catch (e: any) {
    console.log("install error", e);
    throw e;
  } finally {
    if (args.state) args.state.value = "initial";
  }
}

export function copyText(text: string) {
  navigator.clipboard
    .writeText(text)
    .then(() => void message.success("复制成功"))
    .catch(() => void message.error("复制失败"));
}
